import * as THREE from "three";
import { threeViewStore } from "../../store/models/data";
import pinia from '../../store/index';
let pointsArrV3: any = [];
// let objArr = [];//存放绘制的模型的数组
// let lineObjArr: any = [];//存放线的模型数组
// let labelTextArr: any = [];//存放标签模型的数组
let pointIndexTag = true;
let moveFlag = false;
let FloorObject: THREE.Mesh;
let clickNum = 0;
const store = threeViewStore(pinia);
export default function height(heightVis: any) {
    let domContainer = document.getElementById("threeContainer");
    console.log('函数调用点击');
    clickNum =0;
    // store.lineObjArr =[];
    if (heightVis) {
        // store.lineObjArr =[];
        // store.labelTextArr=[];
        domContainer.style.cursor = "crosshair";
        domContainer?.addEventListener("mousedown", onmousedown);
        window.controls.addEventListener("change", onPointerMove);
        domContainer?.addEventListener("mouseup", onClick);
        // 加载地板作为辅助射线交汇坐标点
        // const loader = new THREE.TextureLoader();
        // const texture = loader.load("/img/muwen.png");
        const geometry = new THREE.BoxGeometry(100, 0.1, 100);
        // const material = new THREE.MeshBasicMaterial({ map: texture });
        const material = new THREE.MeshBasicMaterial({
            color: 0xffffff,
            // side: THREE.DoubleSide,
            transparent: true, // 设置为true，opacity才会生效
            opacity: 0.3,
        });
        if (!FloorObject) {
            FloorObject = new THREE.Mesh(geometry, material);
            FloorObject.position.set(0, -1.5, 0);
            window.threeScene.add(FloorObject);
        }
    }
    else {
        domContainer.style.cursor = "default";
        domContainer?.removeEventListener("mousemove", onMousemove);
        domContainer?.removeEventListener("mouseup", onClick);
        domContainer?.removeEventListener("mousedown", onmousedown);
        window.controls.removeEventListener("change", onPointerMove);
        // 卸载地板
        // window.threeScene.remove(FloorObject);
    }
}

function onmousedown() {
    moveFlag = false;//如果鼠标发生了移动，就将moveFlag设置为false,则不再触发onPointerClick方法，即不再绘制点
}
function onPointerMove() {
    moveFlag = true;
}

function onClick(event: any) {
    clickNum++;
    if (!moveFlag) {
        // 如果当前是绘制的第一个点就监听触发mousemove,如果绘制的是第二个点，就结束绘制
        // 在mousemove的过程中动态计算各边数据
         if (clickNum%2 != 0) {
            pointIndexTag = true;
        }
        else {
            pointIndexTag = false;
        }
        console.log(pointIndexTag,clickNum,'-----');
        
        if (pointIndexTag) {
            // 绘制点
            const pointer = new THREE.Vector2();
            pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
            pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
            const raycaster = new THREE.Raycaster();
            raycaster.setFromCamera(pointer, window.camera);
            let position = [];
            const intersects = raycaster.intersectObjects(window.threeScene.children, true);
            if (intersects.length > 0) {
                let index = 0;
                let x = intersects[index].point.x;
                let y = intersects[index].point.y;
                let z = intersects[index].point.z;
                position.push(x);
                position.push(y);
                position.push(z);
                const vposition = intersects[0].point;
                pointsArrV3 = [];
                window.threeScene.remove(drawpointObj);
                pointsArrV3.push(vposition);
                console.log(pointsArrV3, '有点了');
                let drawpoint = drawPoint(position);
                store.objArr.push(drawpoint);
            }
            // 触发mousemove
            let domContainer = document.getElementById("threeContainer");
            domContainer?.addEventListener("mousemove", onMousemove);
        }
        else {
            // 清空
            console.log(store.lineObjArr.length, '我点击了');
        }
    }

}
function onMousemove(event: any) {
    if (pointIndexTag) {
        // 监听点坐标，动态绘制三条线，根据这已经画的点坐标和mousemove的坐标
        const pointer = new THREE.Vector2();
        pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
        pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(pointer, window.camera);
        const intersects = raycaster.intersectObjects(window.threeScene.children, true);
        if (intersects.length > 0) {
            const vposition = intersects[0].point;
            // 使用vposition作为 第二个点坐标，绘制三条边
            console.log(vposition, '移动拾取');
            // 绘制三条边，同时计算第三个点
            drawTriangle(vposition, event);
        }

    }
}
let drawpointObj;
// 绘制点的函数
function drawPoint(position: any) {
    const geometry = new THREE.BufferGeometry();
    const color = new Float32Array([1, 0, 0]);
    // console.log(position, 'position3');
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3));

    geometry.setAttribute('color', new THREE.BufferAttribute(color, 3));
    geometry.computeBoundingSphere();
    // 定义材质
    // 如果需要绘制点线可以被模型遮挡，把depthTest设置为true即可
    const material = new THREE.PointsMaterial({ size: 0.1, vertexColors: true, depthTest: false });
    const drawpoint = new THREE.Points(geometry, material);
    drawpointObj = drawpoint;
    window.threeScene.add(drawpoint);
    return drawpoint;
}
// 绘制其余三条边和第三个点
function drawTriangle(p2Point: any, event: any) {
    let tx, ty, tz;
    let p3Point;
    if (pointsArrV3[0].y > p2Point.y) {
        ty = pointsArrV3[0].y;
        tx = p2Point.x;
        tz = p2Point.z;
        p3Point = new THREE.Vector3(tx, ty, tz);
    }
    else {
        ty = p2Point.y;
        tx = pointsArrV3[0].x;
        tz = pointsArrV3[0].z;
        p3Point = new THREE.Vector3(tx, ty, tz);
    }


    // 绘制线
    // 三条
    let v1v2Array = [];
    let v1v3Array = [];
    let v2v3Array = [];
    v1v2Array.push(...pointsArrV3[0]);
    v1v2Array.push(...p2Point);
    v1v3Array.push(...pointsArrV3[0]);
    v1v3Array.push(...p3Point);
    v2v3Array.push(...p2Point);
    v2v3Array.push(...p3Point);
    // console.log(v1v2Array, 'v1v2Array', v1v3Array, 'v1v3Array', v2v3Array, 'v2v3Array');
    if (store.lineObjArr.length === 3) {
        console.log(store.lineObjArr, 'store.lineObjArr');

        // 使spanlabel跟随屏幕模型旋转而旋转，而不是固定在某一屏幕座标处
        store.lineObjArr[0].onBeforeRender = function () {
            let pointLabel = new THREE.Vector3().lerpVectors(p2Point, pointsArrV3[0], 0);
            let pointLabelv2 = WorldtoScreenPosition(pointLabel, event);
            // console.log(pointLabelv2,'pointLabelv2');
            store.labelTextArr[0].style.left = pointLabelv2.x + 'px';
            store.labelTextArr[0].style.top = pointLabelv2.y + 'px';

            let pointLabel1 = new THREE.Vector3().lerpVectors(pointsArrV3[0], p3Point, 0);
            let pointLabel1v2 = WorldtoScreenPosition(pointLabel1, event);
            // console.log(pointLabel1v2,'pointLabel1v2');
            store.labelTextArr[1].style.left = pointLabel1v2.x + 'px';
            store.labelTextArr[1].style.top = pointLabel1v2.y + 'px';

            let pointLabel2 = new THREE.Vector3().lerpVectors(p3Point, p2Point, 0)
            let pointLabel2v2 = WorldtoScreenPosition(pointLabel2, event);
            // console.log(pointLabel2v2,'pointLabel2v2');
            store.labelTextArr[2].style.left = pointLabel2v2.x + 'px';
            store.labelTextArr[2].style.top = pointLabel2v2.y + 'px';
        }
        // 如果已经绘制过线就只需要修改线位置即可
        store.lineObjArr[0].geometry.attributes.position = new THREE.Float32BufferAttribute(v1v2Array, 3);
        store.lineObjArr[1].geometry.attributes.position = new THREE.Float32BufferAttribute(v1v3Array, 3);
        store.lineObjArr[2].geometry.attributes.position = new THREE.Float32BufferAttribute(v2v3Array, 3);
        // 标签已经创建过了，只需修改标签的innerhtml即可
        console.log(pointsArrV3[0].distanceTo(p2Point).toFixed(2),'pointsArrV3[0].distanceTo(p2Point).toFixed(2)');
        console.log(store.labelTextArr,'store.labelTextArr');
        
        store.labelTextArr[0].innerHTML = '空间距离' + pointsArrV3[0].distanceTo(p2Point).toFixed(2) + 'm';
        store.labelTextArr[1].innerHTML = '水平距离' + pointsArrV3[0].distanceTo(p3Point).toFixed(2) + 'm';
        store.labelTextArr[2].innerHTML = '高度差' + p3Point.distanceTo(p2Point).toFixed(2) + 'm';
    }
    else {

        drawLine(v1v2Array, event, pointsArrV3[0], p2Point, 'red');
        drawLine(v1v3Array, event, pointsArrV3[0], p3Point, 'green');
        drawLine(v2v3Array, event, p2Point, p3Point, 'blue');
    }

}
/**绘制线*/
function drawLine(pointsArr: any, event: any, pointa: any, pointb: any, fontcolor: any) {
    const geometry = new THREE.BufferGeometry();
    // const color = new Float32Array([1, 0, 0]);
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(pointsArr, 3));
    // geometry.setAttribute('color', new THREE.BufferAttribute(linecolor, 3));
    geometry.computeBoundingSphere();
    let material = new THREE.LineBasicMaterial({ vertexColors: false, depthTest: false, color: 0xFF0000 });
    // 定义三个颜色变量使三条线颜色不同，字体和线条同一个颜色，折中解决区分哪个边对应多少数据的问题，因为没有解决把标签放置到线中间位置的办法
    switch (fontcolor) {
        case 'red':
            material = new THREE.LineBasicMaterial({ vertexColors: false, depthTest: false, color: 0xFF0000 });
            break;
        case 'green':
            material = new THREE.LineBasicMaterial({ vertexColors: false, depthTest: false, color: 0x008000 });
            break;
        case 'blue':
            material = new THREE.LineBasicMaterial({ vertexColors: false, depthTest: false, color: 0x0000FF });
            break;

    }
    const line = new THREE.Line(geometry, material);
    line.frustumCulled = false;//这行代码很关键,让屏幕外区域的点,正确显示
    window.threeScene.add(line);
    drawLabel(line, event, pointa, pointb, fontcolor)
    store.lineObjArr.push(line);
}
/**绘制label */
function drawLabel(line: any, event: any, pointa: any, pointb: any, fontcolor: any) {
    console.log('drawlabel');
    // 绘制标签展示距离，需要计算起点和终点之间的距离。通过与真实环境下的距离进行换算
    // 设置标签展示位置
    let labelText = document.createElement('span');
    store.labelTextArr.push(labelText);
    labelText.style.position = 'absolute';
    labelText.style.top = '0';
    labelText.style.color = fontcolor;
    labelText.style.pointerEvents = 'none';
    document.body.appendChild(labelText);
    // 源代码是构建虚线的时候才实时渲染
    // line.onBeforeRender = function () {
    //     // 设置标签位置，实时渲染
    //     setLabelPosition(labelText, event, pointa, pointb);
    // }
}
/**动态渲染修改标签位置 */
function setLabelPosition(labelText: any, event: any, pointa: any, pointb: any) {
    // let pointLabel = new THREE.Vector3().lerpVectors(pointb, pointa, 0);
    // pointLabel = WorldtoScreenPosition(pointLabel, event);

    // labelText.style.left = pointLabel.x + 40 + 'px';
    // labelText.style.top = pointLabel.y + 5 + 'px';
    /** 坐标转换，再把vector3坐标转为屏幕坐标*/

}
function WorldtoScreenPosition(pos: any, eve: any) {
    // const worldVector = new THREE.Vector3(pos.x, pos.y, pos.z)
    const standardVector = pos.project(window.camera);// 进行投影转换，不太懂为啥转，里面执行了啥操作
    const widthHalf = eve.view.innerWidth / 2;
    const heightHalf = eve.view.innerHeight / 2;
    return {
        x: Math.round(standardVector.x * widthHalf + widthHalf),
        y: Math.round(-standardVector.y * heightHalf + heightHalf),
        z: 1
    }
}